package user

import (
	"encoding/json"
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/go-pay/gopay"
	"github.com/go-pay/gopay/wechat"
	"github.com/gorilla/websocket"
	"io/ioutil"
	"math/rand"
	"net/http"
	"net/url"
	"strconv"
	"time"
	"zhuandan/utils"

	//"time"
	"zhuandan/data_source"
	"zhuandan/models"
)

var (
	appId     = "wxf64aa6106b875289"
	appSecre  = "dad526019f10a9d8acf67b225948563a"
	mchId     = "1662979262"
	apiKey    = "sharesharesharesharesharesharesh"
	mchIdywd  = "1500681281"
	apiKeyywd = "sharesharesharesharesharesharesh"
)

type PayBody struct {
	Uid   int64   `json:"uid" from:"uid"`
	Price float64 `json:"price" from:"price"`
	State string  `json:"state" from:"state"`
}

// 微信支付
func Wechatpay(ctx *gin.Context) {
	request := PayBody{}
	ctx.ShouldBind(&request)

	//id := request.ID
	uid := request.Uid
	price := request.Price
	//var pkg models.Buypackage
	//data_source.Db.Where("id = ?", id).First(&pkg)
	var user models.User
	data_source.Db.Where("id = ?", uid).First(&user)

	orderno := Generate(time.Time{})

	orderadd := models.Buyorder{
		Uid:     uid,
		Addtime: time.Now().Unix(),
		Status:  1,
		Orderno: orderno,
		Price:   price,
	}
	data_source.Db.Create(&orderadd)
	client := wechat.NewClient(appId, mchId, apiKey, true)
	client.SetCountry(wechat.China)
	client.AddCertPemFilePath("upload/apiclient_cert.pem", "upload/apiclient_key.pem")
	money1 := price * 10
	money2 := int(money1 * 10)
	//初始化参数Map
	bm := make(gopay.BodyMap)
	//OrderNo := util.RandomString(32)

	bm.Set("nonce_str", Generate(time.Time{})).
		Set("body", "商品购买").
		Set("out_trade_no", orderno).
		Set("total_fee", money2).
		Set("spbill_create_ip", ctx.ClientIP()).
		Set("notify_url", pturl+"/user/wechatNotify").
		Set("trade_type", wechat.TradeType_JsApi).
		Set("sign_type", wechat.SignType_MD5).
		Set("openid", user.RoutineOpenid)

	//请求支付下单，成功后得到结果
	wxRsp, err := client.UnifiedOrder(ctx, bm)
	fmt.Println(wxRsp)
	timeStamp := strconv.FormatInt(time.Now().Unix(), 10)
	packages := "prepay_id=" + wxRsp.PrepayId // 此处的 wxRsp.PrepayId ,统一下单成功后得到
	paySign := ""
	paySign = wechat.GetJsapiPaySign(appId, wxRsp.NonceStr, packages, wechat.SignType_MD5, timeStamp, apiKey)
	//fmt.Println(paySign)
	//return
	data := map[string]interface{}{
		"appId":     wxRsp.Appid,
		"timeStamp": timeStamp,
		"nonceStr":  wxRsp.NonceStr,
		"package":   packages,
		"signType":  wechat.SignType_MD5,
		"sign":      paySign,
		"orderno":   orderno, // 订单号
	}

	if err != nil {
		ctx.JSON(http.StatusOK, gin.H{
			"code": -1,
			"msg":  "稍后再试",
			"data": gin.H{},
		})
		return
	}
	ctx.JSON(http.StatusOK, gin.H{
		"code":    0,
		"msg":     "ok",
		"error":   0,
		"success": 200,
		"data":    data,
	})
	return
}

// @Summary 微信支付回调
// @Produce  json
// @Success 200 {string} string "success"
// @Router /v1/wechat_notify [post]
func WechatNotify(c *gin.Context) {

	notifyRsp, err := wechat.ParseNotifyToBodyMap(c.Request)
	//fmt.Println(notifyRsp)
	if err != nil {
		c.String(200, "error")
		return
	}
	ok, errSign := wechat.VerifySign(apiKey, wechat.SignType_MD5, notifyRsp)
	if ok { // 验证成功
		fmt.Println("errSign = ", errSign)
		//fmt.Println(notifyRsp["out_trade_no"].(string))
		Zhifupay(notifyRsp["out_trade_no"].(string))
		c.String(200, "success")
		return
	}
	c.String(200, "error")
	return
}

// 支付完成
func Zhifupay(order string) {
	var orders models.Buyorder
	data_source.Db.Where("orderno = ?", order).First(&orders)
	data_source.Db.Model(&models.Buyorder{}).Where("orderno = ?", order).Update("status", 2)

	log1 := models.Log1{
		Uid:     orders.Uid,
		Addtime: time.Now().Unix(),
		Text:    "修改订单状态成功",
		Orderno: order,
	}
	data_source.Db.Create(&log1)
	var user_info models.User
	data_source.Db.Where("id = ?", orders.Uid).First(&user_info)
	log3 := models.Log1{
		Uid:     orders.Uid,
		Addtime: time.Now().Unix(),
		Text:    "查询转单宝用户信息访问接口：" + user_info.Unionid,
		Orderno: order,
	}
	data_source.Db.Create(&log3)
	data_source.Db.Model(&models.User{}).Where("id = ?", orders.Uid).Update("price", user_info.Price+orders.Price)
	userpricenew := models.Userpricenew{
		Uid:     orders.Uid,
		Addtime: time.Now().Unix(),
		State:   1,
		Price:   orders.Price,
		Title:   "充值余额",
		Dqprice: user_info.Price + orders.Price,
	}
	data_source.Db.Create(&userpricenew)

	var buypackage models.Buypackage
	data_source.Db.Where("id = 13").First(&buypackage)

	if orders.Price == buypackage.Price+buypackage.Songprice {
		if user_info.Vip == 1 {
			userupdate := models.User{
				Vip:        2,
				Vipinttime: time.Now().Unix(),
				Vipendtime: time.Now().Unix() + 86400*180,
			}
			data_source.Db.Where("id = ?", orders.Uid).Updates(&userupdate)
		} else if user_info.Vip == 2 {
			userupdate := models.User{
				Vip:        2,
				Vipendtime: user_info.Vipendtime + 86400*180,
			}
			data_source.Db.Where("id = ?", orders.Uid).Updates(&userupdate)
		}
	}

	//if user_info.Ywdgzheopenid != "" {
	//
	//	var weixin models.YwWeixin
	//	data_source.OtherDb.Where("unionid = ?", user_info.Unionid).First(&weixin)
	//	//Appaccountmoney(user.Unionid, "商机购买扣除", "2", price)
	//
	//	data_source.OtherDb.Model(&models.YwWeixin{}).Where("unionid = ?", user_info.Unionid).Update("money", weixin.Money+orders.Price)
	//
	//	account_money := models.YwAccountMoney{
	//		AccountId:   weixin.ID,
	//		Money:       orders.Price,
	//		RemainMoney: weixin.Money + orders.Price,
	//		Ctime:       time.Now().Unix(),
	//		Memo:        "用户充值余额",
	//		Type:        1,
	//	}
	//	data_source.OtherDb.Create(&account_money)
	//
	//	//data := Appaccountuser(user_info.Unionid)
	//
	//	//
	//	//r := Appaccountmoney(user_info.Unionid, "用户充值余额", "1", orders.Price)
	//	//if r.Status == 1 {
	//	//	data_source.Db.Model(&models.User{}).Where("id = ?", orders.Uid).UpdateColumn("price", gorm.Expr("price + ?", orders.Price))
	//	//	data_source.Db.Model(&models.Buyorder{}).Where("orderno = ?", order).Update("state", 2)
	//	//
	//	//}
	//}

	//if data.User.AccountId != "" {
	//	price := utils.StrToFloat64(data.User.Money) + orders.Price
	//	data_source.Db.Model(&models.User{}).Where("id = ?", orders.Uid).Update("price", price)
	//	Appaccountmoney(user_info.Unionid, "用户充值余额", "1", orders.Price)
	//} else {
	//
	//	data_source.Db.Model(&models.User{}).Where("id = ?", orders.Uid).UpdateColumn("price", gorm.Expr("price + ?", orders.Price))
	//}

}
func WechatNotifycs(ctx *gin.Context) {
	request := PayBody{}
	ctx.ShouldBind(&request)
	uid := request.Uid
	price := request.Price
	state := request.State
	var user models.User
	data_source.Db.Where("id = ?", uid).First(&user)

	Appaccountmoney(user.Unionid, "扣除余额", state, price)
	ctx.String(200, "success")
	return
}

func Appaccountmoney(unionid, memo, typezf string, money float64) (data Responsewxuserdata) {
	value := url.Values{"token": {"yanwei123yanwei123yanwei123yanwe"}, "action": {"app_account_money_change"}, "unionid": {unionid}, "type": {typezf}, "money": {utils.FloatToStr64(money)}, "memo": {memo}}
	//fmt.Println(value)
	resp, err := http.PostForm("https://data.yewudaotech.com/interface.php", value)
	if err != nil {
		fmt.Println(err)
		return
	}
	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)
	r := Responsewxuserdata{}
	fmt.Println(string(body))
	log := models.Log{
		Unionid: unionid,
		Addtime: time.Now().Unix(),
		Text:    string(body),
		Title:   "修改用户余额",
	}
	data_source.Db.Create(&log)
	//把请求到的结构反序列化到专门接受返回值的对象上面
	err = json.Unmarshal(body, &r)
	if err != nil {
		fmt.Println(err)
	}
	return r
}

func timeWriter(conn *websocket.Conn) {
	for {
		time.Sleep(time.Second * 5)
		conn.WriteMessage(websocket.TextMessage, []byte(time.Now().Format("2006-01-02 15:04:05")))
	}
}

type TuikuanBody struct {
	ID int64 `json:"id" from:"id"`
}

// 微信支付退款
func Wechattuikuan(ctx *gin.Context) {
	request := TuikuanBody{}
	ctx.ShouldBind(&request)

	id := request.ID
	data_source.Db.Model(&models.Order{}).Where("id = ?", id).Update("status", 4)

	ctx.JSON(http.StatusOK, gin.H{
		"code":    0,
		"msg":     "ok",
		"error":   0,
		"success": 200,
		"data":    "ok",
	})
	return
}

var ordernum int64

func Generate(t time.Time) string {
	// 生成当前日期部分（例如：20231008）
	datePart := time.Now().UnixNano()
	// 生成随机数部分（4位随机数）
	rand.Seed(time.Now().UnixNano())
	randomPart := fmt.Sprintf("%04d", rand.Intn(10000))
	// 最终的订单号由前缀、日期和随机数部分组成
	orderNumber := utils.Int64string(datePart) + randomPart
	return orderNumber
}

// 对长度不足n的数字前面补0
func sup(i int64, n int) string {
	m := fmt.Sprintf("%d", i)
	for len(m) < n {
		m = fmt.Sprintf("0%s", m)
	}
	return m
}
